package com.siao.loader
{
	import com.siao.component.gif.events.FileTypeEvent;
	import com.siao.component.gif.events.GIFPlayerEvent;
	import com.siao.component.gif.events.TimeoutEvent;
	import com.siao.component.gif.player.GIFPlayer;
	import com.siao.events.BytesEvent;
	import com.siao.utils.json.Json;
	
	import flash.display.AVM1Movie;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.utils.ByteArray;
	
	[Event(name="complete", type="com.siao.events.BytesEvent")]
	
	[Event(name="error", type="com.siao.events.BytesEvent")]
	
	/**
	 * 二进制解析器
	 * @author SiaoLeon
	 */
	public class BytesResolver extends EventDispatcher
	{
		// -------------------------------------------------------------------------------------------------------- 静态常量
		
		// -------------------------------------------------------------------------------------------------------- 静态变量
		
		// -------------------------------------------------------------------------------------------------------- 静态方法
		
		// -------------------------------------------------------------------------------------------------------- 静态函数
		
		// -------------------------------------------------------------------------------------------------------- 属性
		
		private var _content:*;
		
		/**
		 * 二进制内容
		 * @return
		 */
		public function get content():*
		{
			return this._content;
		}
		
		// -------------------------------------------------------------------------------------------------------- 变量
		
		private var loader:Loader;
		
		private var gif:GIFPlayer;
		
		// -------------------------------------------------------------------------------------------------------- 构造
		
		/**
		 * 构造函数
		 */
		public function BytesResolver()
		{
			super();
			
			this.loader = new Loader();
			this.loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
			this.loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError);
			
			this.gif = new GIFPlayer();
			this.gif.addEventListener(GIFPlayerEvent.COMPLETE, onComplete);
			this.gif.addEventListener(IOErrorEvent.IO_ERROR, onError);
			this.gif.addEventListener(TimeoutEvent.TIME_OUT, onError);
			this.gif.addEventListener(FileTypeEvent.INVALID, onError);
		}
		
		// -------------------------------------------------------------------------------------------------------- 方法
		
		/**
		 * 解析
		 * @param bytes 字节数据
		 * @param isFull 是否为完整数据
		 */
		public function parser(bytes:ByteArray, isFull:Boolean=true):void
		{
			var type:uint = bytes.readUnsignedShort();
			bytes.position = 0;
			
			try
			{
				switch (type)
				{
					case 15423: //XML
					case 61371:
						if (isFull)
						{
							this.save(new XML(bytes));
						}
						break;
					
					case 18249: //GIF
						if (isFull)
						{
							this.gif.loadBytes(bytes);
						}
						break;
					
					case 65496: //JPG
					case 35152: //PNG
					case 17239: //SWF
					case 23127: //SWF
					case 18007:
						var context:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
						context.allowCodeImport = true;
						this.loader.loadBytes(bytes, context);
						break;
					
					default:
						try
						{
							this.save(Json.decode(bytes.toString()));
						}
						catch (err:Error)
						{
							trace("未知的文件类型：", type);
							this.save(bytes);
							break;
						}
				}
			}
			catch (err:Error)
			{
				trace(err.message);
				this.onError();
			}
		}
		
		// -------------------------------------------------------------------------------------------------------- 函数
		
		/**
		 * 保存数据内容
		 * @param content 内容对象
		 */
		protected function save(content:*):void
		{
			this._content = content;
			this.dispatchEvent(new BytesEvent(BytesEvent.COMPLETE));
		}
		
		/**
		 * 解析完成时
		 * @param event
		 */
		private function onComplete(event:Event):void
		{
			switch (event.target)
			{
				case this.gif:
					this.save(this.gif);
					break;
				
				case this.loader.contentLoaderInfo:
					this.save((this.loader.content is AVM1Movie) ? this.loader : this.loader.content);
					this.loader.unload();
					break;
			}
		}
		
		/**
		 * 解析错误时
		 * @param event
		 */
		private function onError(event:Event=null):void
		{
			this.dispatchEvent(new BytesEvent(BytesEvent.ERROR));
		}
	
	}
}
